// // fetchAll([
// //   'https://www.baidu.com',
// //   'http://www.google.com',
// //   'https://www.bytedance.com',
// //   'https://www.tx.com'
// // ], 3).then(res => {
// //     console.log(res.length); // 4
// //   })

// fetchAll([1, 2, 3, 4], 3).then(res => {
//   console.log(res);
//   console.log(res.length); // 4
// })

function fetchAll(urls, maxNum) {
  return new Promise((resolve) => {
    if (urls.length === 0) {
      resolve([]);
      return;
    }
    const res = [];
    let index = 0;
    let count = 0
    async function request() {
      const url = urls[index];
      let i = index;
      index++;
      try {
        const resp = await fetch(url);
        res[i] = resp;
      } catch (err) {
        res[i] = err;
      } finally {
        count++;
        if (count === urls.length) resolve(res);
        if (index < urls.length) {
          request();
        }
      }
    }
    for (let i = 0; i < Math.min(urls.length, maxNum); i++) {
      request();
    }
  });
}

/**
 * 并发请求
 * @param {string[]} urls 待请求的url数组
 * @param {number} maxNum 最大并发数
 */

function concurRequest(urls, maxNum) {
  return new Promise((resolve) => {
    if (urls.length === 0) {
      resolve([]);
      return;
    }

    const res = [];
    let index = 0; // 下一个请求的下标
    let count = 0; // 当前请求的数量
    // 发送请求
    async function request() {
      // 递归结束
      if (index === urls.length) return;
      const i = index;
      const url = urls[index];
      index++;
      try {
        const resp = await fetch(url);
        // 结果加入res
        res[i] = resp;
      } catch (err) {
        res[i] = err;
      } finally {
        // 判断所有的请求是否完成
        count++;
        if (count === urls.length) {
          resolve(res);
        }
        request();
      }
    }

    const min = Math.min(maxNum, urls.length);

    for (let i = 0; i < min; i++) {
      request();
    }
  });
}

concurRequest(
  [
    'https://www.baidu.com',
    'http://www.google.com',
    'https://www.bytedance.com',
    'https://www.tx.com',
  ],
  3,
).then((res) => {
  console.log(res); // 4
});
